import { convertToWhere } from './SpringJpaUtil';
import {
  PrimaryColumn,
  Generated,
  EntityTarget,
  FindOptionsRelations,
  FindOptionsOrder,
} from 'typeorm';
import { SpringDao } from './SpringRepository';

export type EntityClass = new () => JpaEntity<any>;

export type EntityOption<T> = {
  [P in keyof T]?: T[P];
};

export type EntityList = JpaEntity<any> | JpaEntity<any>[];

export class JpaEntity<T> {
  of(prop?: EntityOption<T>) {
    if (prop) {
      Object.assign(this, prop);
    }
    return this;
  }

  @PrimaryColumn()
  @Generated()
  id: number;

  // @CreateDateColumn()
  // crateTime: Date;
}

export abstract class JpaSearch<
  T extends JpaEntity<T>,
  S extends JpaSearch<T, S>
> {
  constructor(public readonly entityTarget: EntityTarget<T>) {}

  curPage: number = 1;

  pageSize: number = 20;

  of(prop?: EntityOption<S>) {
    if (prop) {
      Object.assign(this, prop);
    }
    return this;
  }

  async find(springDao: SpringDao): Promise<T[]> {
    const e = springDao.getEntityManager();
    return e.find(this.entityTarget, { where: convertToWhere(this) });
  }

  //关联对象
  $relations: FindOptionsRelations<T> = {};

  //级联查询策略
  $relatirelationLoadStrategy?: 'join' | 'query' = 'query';

  //缓存策略
  $cache?:
    | boolean
    | number
    | {
        id: any;
        milliseconds: number;
      };

  //sql注释
  $comment: string;

  //排序
  $order?: FindOptionsOrder<T>;

  //是否分页
  $isUsePagin: boolean = false;

  order(r: FindOptionsOrder<T>) {
    this.$order = r;
    return this;
  }

  comment(r: string) {
    this.$comment = r;
    return this;
  }

  cache(
    r:
      | boolean
      | number
      | {
          id: any;
          milliseconds: number;
        }
  ) {
    this.$cache = r;
    return this;
  }

  relation(r: FindOptionsRelations<T>) {
    this.$relations = r;
    return this;
  }

  relatirelationLoadStrategy(r?: 'join' | 'query') {
    this.$relatirelationLoadStrategy = r;
    return this;
  }

  usePagin() {
    this.$isUsePagin = true;
    return this;
  }
}
